package cmarter.dev.chpt2;

import java.util.ArrayList;
import java.util.List;

import cmarter.dev.chpt2.interfaces.ApplePredicate;
import cmarter.dev.entities.Apple;

public class FarmingInventory {		
		
		// naive approach
		// Dosen't lend itself to changing requirements such
		// as filtering on multiple colored apples { red, yellow, green, so on }
		public static List<Apple> filterGreenApples(List<Apple> inventory) {
			List<Apple> result = new ArrayList<Apple>();
			for (Apple a : inventory) {
				if ("green".equals(a.getColor())) {
					result.add(a);
				}
			}
			return result;
		}	
		
		// better approach
		// Dosen't lend itself to changing requirements such
		// as filtering on different attributes of the apples such as weight
		/**
		 * ALSO NOW IF YOU CHANGE THE OBJECT (apple) YOU HAVE TO CHANGE MULTIPLE FUNCTIONS
		 * 
		 * **/
		public static List<Apple> filterApplesByWeight(List<Apple> inventory, int weight) {
			List<Apple> result = new ArrayList<Apple>();
			for (Apple a : inventory) {
				if ( a.getWeight() > weight) {
					result.add(a);
				}
			}
			return result;
		}
		
		
		
	// Nasty approach is to filter on all attributes of Apple
	// very ugly and doesn't cope well with changing requirements, this method
	// behavior depends on flag
	/**
	 * ALSO NOW IF YOU CHANGE THE OBJECT (apple) YOU HAVE TO CHANGE MULTIPLE
	 * FUNCTIONS
	 * 
	 * **/
	public static List<Apple> filterApplesByWeight(List<Apple> inventory, String color, String name, int weight, boolean flag) {
		List<Apple> result = new ArrayList<Apple>();
		for (Apple a : inventory) {
			if (flag && a.getColor().equals("green") || flag
					&& a.getWeight() > weight) {
				result.add(a);
			}
		}
		return result;
	}	
		
	// Proper Java 8 way using predicates
	/**
	 * NOW YOU CHANGE THE OBJECT (apple) and author a corresponding predicate
	 * 
	**/
	public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {
		List<Apple> result = new ArrayList<Apple>();
		for (Apple a : inventory) {
			if (p.test(a)) {
				result.add(a);
			}
		}
		return result;
	}
}
